<?php

    $rootDir = $_SERVER['DOCUMENT_ROOT'];

    require_once($rootDir.'/functions.php');
    require_once($rootDir.'/classes/SessionManager.class.php');
    require_once($rootDir.'/classes/db/SQLiteConnector.class.php');
    require_once($rootDir.'/classes/LeproUser.class.php');   
    require_once($rootDir.'/classes/db/LeproUserDAO.class.php');
    require_once($rootDir.'/classes/LeproBJGroup.class.php');   
    require_once($rootDir.'/classes/db/LeproBJGroupDAO.class.php');    
    require_once($rootDir.'/classes/LeproHelper.class.php');
    require_once($rootDir.'/classes/Card.class.php');
    require_once($rootDir.'/classes/LeproBJAppSettings.class.php');
    require_once($rootDir.'/classes/UserStatsImageGenerator.class.php');    
    require_once($rootDir.'/classes/mutex/GroupWriteMutex.class.php');

    $tUID = urldecode($_POST['uid']);
    $tGID = urldecode($_POST['gid']);
    $tACT = urldecode($_POST['act']);
    $tCOD = urldecode($_POST['code']);
        
    date_default_timezone_set('Europe/Moscow');   
        
    class GPResultConstants {
    
        const NO_ERRORS = 0;
        const NOT_LOGGED = -1;
        const NOT_MATCHED = -2;
        const NOT_CONNECTED = -3;
        const NOT_LOADED = -4;
        const NOT_PASSED = -5;
        const NOT_ALLOWED = -6;
        const NUMBER_LIMIT = -7;
        const UNKNOWN_ACTION = -8;
        const JOIN_RESTRICTED = -9;
        const ALREADY_CREATED = -10;
        const HAVE_MET_ALREADY = -11;
        const SCORE_NOT_REACHED = -12;
    
    }    
    
    if (SessionManager::isUserLoggedIn()) {
        $userId = SessionManager::getCurrentUserID(); // TODO: check dirty variant
        if (($userId != null) && ($tUID == $userId) && (preg_match("/^\d*$/", $tUID) > 0) 
            && SessionManager::isUserChecked($tUID)
            && ((strlen($tGID) == 0) || (preg_match("/^\d*$/", $tGID) > 0)) 
            && (preg_match("/^[cjlt]$/", $tACT) > 0)
            && ((strlen($tCOD) == 0) || (preg_match("/^[A-Za-z0-9]*$/", $tCOD) > 0))) {
            //GroupWriteMutex::initialize();
            $connector = SQLiteConnector::getInstance();
            if ($connector->connect()) { // connect to DB                
                $userDAO = new LeproUserDAO($connector->getDB());
                $groupDAO = new LeproBJGroupDAO($connector->getDB()); 
                $user = $userDAO->load($userId); // try to load this user from DB
                if ($user != null) {
                    $weekDay = date("w");
                    GroupWriteMutex::acquireWriteAccess();
                    $group = null;
                    $groupsCount = $groupDAO->getCount();
                    $result = GPResultConstants::NO_ERRORS;
                    $actPerformed = false;
                    $userNotInGroup = false;
                    /* echo '>>>'.$tACT.'<<<'; */                         
                    switch ($tACT) {
                        case 'c': {
                            if ((strlen($tGID) == 0) && ($user->inGroup($tGID) === false)) {
                                $userCard = $user->getCardID();
                                if ($userCard[0] != 'f') {
                                    if ($groupDAO->userGroupsCount($userId) == 0) {
                                        $group = new LeproBJGroup($groupsCount + 1, $tCOD);
                                        $group->setCreationTime(time());
                                        $group->addUser($user);
                                        $actPerformed = true;
                                    } else $result = GPResultConstants::ALREADY_CREATED; 
                                } else $result = GPResultConstants::JOIN_RESTRICTED;
                            } else $result = GPResultConstants::NOT_ALLOWED;
                        } break;
                        case 'j': {                       
                            if (((int)$tGID <= $groupsCount) && ($user->inGroup($tGID) === false)) {
                                $ugc = $user->getGroupsCount();
                                $uscore = $user->getGScore();
                                $scoreApproved = ($ugc == 0) || ($ugc % 10 != 0);
                                if (!$scoreApproved) $scoreApproved = ($uscore >= bcmul(0.7, $ugc - ($ugc % 10), 0));
                                if ($scoreApproved) {                                
                                    $group = $groupDAO->load($tGID);
                                    if ($groupDAO->numOfCrossMeets($userId, $group->getUsersIDs()) == 0) {   
                                        if ((strlen(trim($group->getCode())) == 0) || (strcmp($tCOD, $group->getCode()) == 0)) {
                                            $group->addUser($user);
                                            $actPerformed = true;
                                        } else $result = GPResultConstants::NOT_PASSED;
                                    } else $result = GPResultConstants::HAVE_MET_ALREADY;
                                } else $result = GPResultConstants::SCORE_NOT_REACHED;
                            } else $result = GPResultConstants::NOT_ALLOWED;
                        } break;
                        case 'l': case 't': {
                            if (in_array($weekDay, LeproBJAppSettings::$LALLOWED_DAYS) && 
                                ($user->inGroup($tGID) !== false)) {
                                $group = $groupDAO->load($tGID);
                                if ($group->getUsersCount() > 1) { 
                                    if (strcmp($tCOD, $group->getCode()) == 0) {
                                        $group->removeUser($user);
                                        $actPerformed = true;
                                        $userNotInGroup = true;
                                    } else $result = GPResultConstants::NOT_PASSED;
                                } else $result = GPResultConstants::NUMBER_LIMIT;
                            } else $result = GPResultConstants::NOT_ALLOWED;
                        } break;                    
                    }
                    if (($result == GPResultConstants::NO_ERRORS) && ($group !== null) && $actPerformed) {
                        $usersIds = $group->getUsersIDs();
                        $usersCards = $userDAO->getUsersCards($usersIds);
                        $scoreSum = Card::getCardsScoreSum($usersCards);
                        $group->updateScoreSum($scoreSum);
                        $groupDAO->save($group);
                        $userDAO->save($user);
                        if ($userNotInGroup) $usersIds[] = $userId;
                        foreach ($usersIds as $guserId) {
                            $someUser = $userDAO->load($guserId);
                            $groupsIds = $someUser->getGroupsIDs();
                            $gScores = $groupDAO->getGroupsScores($groupsIds);
                            $sumValue = LeproBJGroup::calculateGroupsSumValue($gScores);
                            $someUser->updateGScore($sumValue);
                            $userDAO->save($someUser);
                        }
                        $result = json_encode($group->getSummary());
                        UserStatsImageGenerator::invalidateImage($userId);
                        // echo $scoreSum;                
                    } 
                    if (($group === null) && ($result == GPResultConstants::NO_ERRORS)) $result = GPResultConstants::UNKNOWN_ACTION;
                    GroupWriteMutex::releaseWriteAccess();
                    echo $result;
                } else echo GPResultConstants::NOT_LOADED;                
            } else echo GPResultConstants::NOT_CONNECTED;
        } else echo GPResultConstants::NOT_MATCHED;
    } else echo GPResultConstants::NOT_LOGGED;

?>
